﻿using ApiManage.Applications.Mongo.Sys;
using ApiManage.Models.MongoMappings.Sys;
using ApiManage.Models.RequestModels;
using ApiManage.Service.Mongo.Sys;
using ApiManage.Svc.Filter;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using Rhonin.Common.Entity.Api;
using Rhonin.Common.Entity.Exception;
using Rhonin.Common.Entity.Page;
using Rhonin.Common.Extentions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace ApiManage.Svc.Controllers.System
{
    /// <summary>
    /// 菜单控制器
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class SysMenuController : BaseController
    {
        private readonly ISysMenuService _sysMenuService;
        private readonly ISysMenuQueryService _sysMenuQueryService;
        private readonly ISysButtonService _sysButtonService;
        private readonly ISysButtonQueryService _sysButtonQueryService;
        private readonly ISysColumnService _sysColumnService;
        private readonly ISysColumnQueryService _sysColumnQueryService;
        /// <summary>
        /// 
        /// </summary>
        public SysMenuController(ISysMenuService sysMenuService,
            ISysMenuQueryService sysMenuQueryService,
            ISysButtonService sysButtonService,
            ISysButtonQueryService sysButtonQueryService,
            ISysColumnService sysColumnService,
            ISysColumnQueryService sysColumnQueryService)
        {
            _sysMenuService = sysMenuService;
            _sysMenuQueryService = sysMenuQueryService;
            _sysButtonService = sysButtonService;
            _sysButtonQueryService = sysButtonQueryService;
            _sysColumnService = sysColumnService;
            _sysColumnQueryService = sysColumnQueryService;
        }

        #region 菜单
        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <returns></returns>
        [Route("GetAllMenu"), HttpGet, CheckLogin]
        public ApiResult<List<SysMenu>> GetAllMenu()
        {
            Expression<Func<SysMenu, bool>> where = o => o.Mark != 9;
            var allMenus = _sysMenuQueryService.GetList(where);
            var topMenu = allMenus.Where(o => string.IsNullOrEmpty(o.MenuUp)).OrderBy(o => o.Sort).ToList();
            topMenu.ForEach(item => { GetChildren(item, allMenus); });
            return CreateResult(topMenu);
        }

        private static void GetChildren(SysMenu menu, List<SysMenu> allMenus)
        {
            var children = allMenus.Where(o => !string.IsNullOrEmpty(o.MenuUp) && new ObjectId(o.MenuUp) == menu.Id).OrderBy(o => o.Sort).ToList();
            if (children.Count <= 0) return;
            children.ForEach(item => { GetChildren(item, allMenus); });
            menu.Children = children;
        }

        /// <summary>
        /// 编辑菜单
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("MenuEdit"), HttpPost, CheckLogin]
        public ApiResult MenuEdit(SysMenuExtend param)
        {
            if (string.IsNullOrEmpty(param.MenuName))
                throw new ApiException("菜单名称不能为空");
            if (string.IsNullOrEmpty(param.MenuUrl))
                throw new ApiException("菜单路由不能为空");
            if (string.IsNullOrEmpty(param.Id))
            {
                _sysMenuService.Insert(new SysMenu
                {
                    MenuName = param.MenuName,
                    MenuUrl = param.MenuUrl,
                    MenuIcon = param.MenuIcon,
                    MenuUp = param.MenuUp,
                    Sort = param.Sort,
                    Mark = param.Mark
                });
            }
            else
            {
                _sysMenuService.Update(m => m.Id == new ObjectId(param.Id), Builders<SysMenu>.Update
                    .Set("MenuName", param.MenuName)
                    .Set("MenuUrl", param.MenuUrl)
                    .Set("MenuIcon", param.MenuIcon)
                    .Set("MenuUp", param.MenuUp)
                    .Set("Sort", param.Sort)
                    .Set("Mark", param.Mark)
                );
            }

            return CreateSuccess();
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("MenuDel"), HttpPost, CheckLogin]
        public ApiResult MenuDel(IdParam param)
        {
            _sysMenuService.Delete(m => m.Id == new ObjectId(param.Id));
            return CreateSuccess();
        }
        #endregion

        #region 按钮
        /// <summary>
        /// 分页获取页面按钮
        /// </summary>
        /// <param name="menuId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [Route("PageMenuButton"), HttpGet, CheckLogin]
        public ApiResult<PageResult<SysButton>> PageMenuButton(string menuId, int pageIndex, int pageSize)
        {
            var param = new QueryPage
            {
                PageIndex = pageIndex,
                PageSize = pageSize
            };
            Expression<Func<SysButton, bool>> where = o => o.Mark != 9;
            where = where.AndIf(o => o.MenuId.Equals(menuId), !string.IsNullOrEmpty(menuId));
            var list = _sysButtonQueryService.GetList(where);
            var page = new PageResult<SysButton>
            {
                TotalCount = list.Count,
                Items = list.OrderBy(o => o.Sort).Skip(param.Skip).Take(param.Limit),
                PageParameter = param
            };
            return CreateResult(page);
        }
        /// <summary>
        /// 编辑按钮
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("ButtonEdit"), HttpPost, CheckLogin]
        public ApiResult ButtonEdit(SysButtonExtend param)
        {
            if (string.IsNullOrEmpty(param.MenuId))
                throw new ApiException("归属菜单选择错误");
            if (string.IsNullOrEmpty(param.FullName))
                throw new ApiException("按钮名称不能为空");
            if (string.IsNullOrEmpty(param.EnCode))
                throw new ApiException("按钮标识不能为空");
            if (string.IsNullOrEmpty(param.Id))
            {
                _sysButtonService.Insert(new SysButton
                {
                    MenuId = param.MenuId,
                    Icon = param.Icon,
                    EnCode = param.EnCode,
                    FullName = param.FullName,
                    Sort = param.Sort,
                    Mark = param.Mark
                });
            }
            else
            {
                _sysButtonService.Update(m => m.Id == new ObjectId(param.Id), Builders<SysButton>.Update
                    .Set("MenuId", param.MenuId)
                    .Set("Icon", param.Icon)
                    .Set("EnCode", param.EnCode)
                    .Set("FullName", param.FullName)
                    .Set("Sort", param.Sort)
                    .Set("Mark", param.Mark));
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 删除按钮
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("ButtonDel"), HttpPost, CheckLogin]
        public ApiResult ButtonDel(IdParam param)
        {
            try
            {
                _sysButtonService.Delete(o => o.Id == new ObjectId(param.Id));
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        #endregion

        #region 列
        /// <summary>
        /// 分页获取页面列
        /// </summary>
        /// <param name="menuId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [Route("PageMenuColumn"), HttpGet, CheckLogin]
        public ApiResult<PageResult<SysColumn>> PageMenuColumn(string menuId, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(menuId))
                throw new ApiException("请选择列归属");
            var param = new QueryPage
            {
                PageIndex = pageIndex,
                PageSize = pageSize
            };
            Expression<Func<SysColumn, bool>> where = o => o.Mark != 9;
            where = where.AndIf(o => o.MenuId.Equals(menuId), !string.IsNullOrEmpty(menuId));
            var list = _sysColumnQueryService.GetList(where);
            var page = new PageResult<SysColumn>
            {
                TotalCount = list.Count,
                Items = list.OrderBy(o => o.Sort).Skip(param.Skip).Take(param.Limit),
                PageParameter = param
            };
            return CreateResult(page);
        }
        /// <summary>
        /// 编辑列
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("ColumnEdit"), HttpPost, CheckLogin]
        public ApiResult ColumnEdit(SysColumnExtend param)
        {
            if (string.IsNullOrEmpty(param.MenuId))
                throw new ApiException("归属菜单选择错误");
            if (string.IsNullOrEmpty(param.FullName))
                throw new ApiException("列名称不能为空");
            if (string.IsNullOrEmpty(param.EnCode))
                throw new ApiException("列标识不能为空");
            if (string.IsNullOrEmpty(param.Id))
            {
                _sysColumnService.Insert(new SysColumn
                {
                    MenuId = param.MenuId,
                    Remark = param.Remark,
                    EnCode = param.EnCode,
                    FullName = param.FullName,
                    Sort = param.Sort,
                    Mark = param.Mark,
                });
            }
            else
            {
                _sysColumnService.Update(m => m.Id == new ObjectId(param.Id), Builders<SysColumn>.Update
                    .Set("MenuId", param.MenuId)
                    .Set("Remark", param.Remark)
                    .Set("EnCode", param.EnCode)
                    .Set("FullName", param.FullName)
                    .Set("Sort", param.Sort)
                    .Set("Mark", param.Mark));
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 删除列
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("ColumnDel"), HttpPost, CheckLogin]
        public ApiResult ColumnDel(IdParam param)
        {
            try
            {
                _sysColumnService.Delete(o => o.Id == new ObjectId(param.Id));
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        #endregion
    }
}